package com.test.aop;

/**
 * ProxyFactory类用于生成代理对象，可以根据目标对象的类型选择合适的代理方式
 * 继承自AdvisedSupport，以支持设置目标源、通知器等
 */
public class ProxyFactory extends AdvisedSupport{

    /**
     * 默认构造函数
     */
    public ProxyFactory(){
    }

    /**
     * 构造函数，允许在创建ProxyFactory时指定目标对象
     * @param target 目标对象
     */
    public ProxyFactory(Object target){
        setTargetSource(new SingletonTargetSource(target));
    }

    /**
     * 获取代理对象，使用默认的类加载器
     * @return 代理对象
     */
    public Object getProxy(){
        return createAopProxy().getProxy();
    }

    /**
     * 使用指定的类加载器获取代理对象
     * @param classLoader 类加载器
     * @return 代理对象
     */
    public Object getProxy(ClassLoader classLoader){
        return createAopProxy().getProxy(classLoader);
    }

    /**
     * 创建AopProxy对象，根据目标类的接口情况选择使用JDK动态代理或CGLIB代理
     * @return AopProxy对象
     */
    private AopProxy createAopProxy(){
        if (getTargetClass().getInterfaces().length > 0){
            return new JdkDynamicAopProxy(this);
        }
        return new CglibAopProxy(this);
    }

    /**
     * 添加通知器到ProxyFactory
     * @param advisor 通知器对象
     */
    public void addAdvisors(Advisor advisor){
        super.addAdvisors(advisor);
    }

    /**
     * 判断是否需要对目标类进行代理，根据通知器中的切点表达式判断
     * @param targetClass 目标类
     * @return 如果需要代理返回true，否则返回false
     */
    private boolean isProxyTargetClass(Class<?> targetClass){
        if (targetClass == null){
            return false;
        }
        for (Advisor advisor : getAdvisors()){
            if (advisor instanceof PointcutAdvisor){
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (!pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)){
                    return true;
                }
            }
        }
        return false;
    }
}
